<template>
  <div class="dashboard-container">
    <div class="app-container">
      <page-tools :showBefore="true">
        <!-- 放置左侧插槽内容 -->
        <span slot="before">共{{ total }}条记录</span>
        <!-- 放置右侧插槽内容 -->
        <template v-slot:after>
          <el-button type="success" size="small" class="el-icon-download" @click="$router.push('/import')">
            Excel导入</el-button>
          <el-button type="warning" size="small" class="el-icon-upload2" @click="exportData">
            Excel导出</el-button>
          <el-button type="primary" size="small" class="el-icon-plus" @click="showDialog=true">新增员工
          </el-button>
        </template>
      </page-tools>
      <el-card>
        <el-table :data="empList" v-loading="loading" border>
          <el-table-column prop="" label="序号" sortable="" type="index" />
          <el-table-column label="姓名" sortable="" prop="username" />
          <el-table-column label="头像" sortable="" prop="staffPhoto" width="120px" align="center">
            <template v-slot="scope">
              <img v-imageerror="defaultImg" :src="scope.row.staffPhoto" @click="showQrCode(scope.row.staffPhoto)"
                alt="" class="emp-staff-photo">
            </template>
          </el-table-column>
          <el-table-column label="工号" sortable="" prop="workNumber" />
          <el-table-column label="聘用形式" sortable="" prop="formOfEmployment" :formatter="formatEmployment" />
          <el-table-column label="部门" sortable="" prop="departmentName" />
          <el-table-column label="入职时间" sortable="">
            <!-- 作用域插槽 -->
            <template slot-scope="scope">
              <div>
                <!-- 使用过滤器，格式化时间 -->
                {{ scope.row.timeOfEntry | formatDate }}
              </div>
            </template>
          </el-table-column>
          <el-table-column label="账户状态" sortable="">
            <template slot-scope="scope">
              <el-switch :value="scope.row.enableState === 1" active-color="#13ce66">
              </el-switch>
            </template>
          </el-table-column>
          <el-table-column label="操作" sortable="" fixed="right" width="280">
            <template slot-scope="scope">
              <el-button type="text" size="small" @click="$router.push(`/employees/detail/${scope.row.id}`)">查看
              </el-button>
              <el-button type="text" size="small">转正</el-button>
              <el-button type="text" size="small">调岗</el-button>
              <el-button type="text" size="small">离职</el-button>
              <el-button type="text" size="small" @click="editRole(scope.row.id)">角色</el-button>
              <el-button type="text" size="small" @click="deleteEmployeeById(scope.row)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
        <el-row type="flex" justify="center" align="middle" style="height: 60px">
          <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
            :current-page="pageData.page" :page-sizes="[5, 10, 20, 50]" :page-size="pageData.size"
            layout="total, sizes, prev, pager, next, jumper" :total="total">
          </el-pagination>
        </el-row>
      </el-card>
    </div>
    <!-- 弹出层 -->
    <!-- sync修饰符,子组件关闭弹层时，不需要在父组件监听，只要在子组件触发事件 this.$emit('update:showDialog',false) -->
    <AddEmployee :showDialog.sync="showDialog"></AddEmployee>
    <!-- 二维码弹层 -->
    <el-dialog title="二维码" :visible.sync="showCodeDialog" width="30%" @close="closeCodeDialog">
      <el-row type="flex" justify="center" align="center">
        <canvas ref="codeCanvas"></canvas>
      </el-row>
    </el-dialog>
    <!-- 配置角色的弹层 -->
    <assign-role ref="RoleDialog" :showRoleDialog.sync="showRoleDialog" :userId="roleUserId"></assign-role>
  </div>
</template>

<script>
// 导入API
import { getEmployeeList, deleteEmployeeById } from "@/api/employees";
// 引入枚举数据,实际项目中，更多的是通过接口从后台、数据库中获取
import EmployeeEnum from "@/api/constant/employees";
// 引入组件
import AddEmployee from "./components/add-employee";
// 组件--角色分配
import AssignRole from "./components/assign-role.vue";

// 引入过滤器的方法
import { formatDate } from "@/filters";
// 二维码生成插件
var QRCode = require("qrcode");

export default {
  name: "Employees",
  components: {
    AddEmployee,
    AssignRole,
  },
  data() {
    return {
      // 默认图片，不能直接写路径，免得上线后路径发生变化
      defaultImg: require("@/assets/common/head.jpg"),
      // 总条数
      total: 0,
      pageData: {
        page: 1, //页码
        size: 5, //每页条数
      },
      // 员工数据
      empList: [],
      // 是否加载完成，显示遮罩层
      loading: false,
      // 弹层是否显示
      showDialog: false,
      showCodeDialog: false, //显示二维码弹层
      showRoleDialog: false, //分配角色的弹层显示
      roleUserId: "", //要分配角色的id
    };
  },
  methods: {
    // 获取员工数据
    async getEmployeeList() {
      // 打开加载
      this.loading = true;
      const { total, rows } = await getEmployeeList(this.pageData);
      this.total = total;
      this.empList = rows;
      // 关闭加载
      this.loading = false;
    },
    // 每页条数发送变化，重新请求数据
    handleSizeChange(value) {
      this.pageData.size = value;
      this.getEmployeeList();
    },
    // 当前页码发生变化，重新请求数据
    handleCurrentChange(value) {
      this.pageData.page = value;
      this.getEmployeeList();
    },
    // 格式化数据--聘用形式
    // 参数：行数据，列的属性数据，单元格的值，索引
    formatEmployment(row, column, cellValue, index) {
      let obj = EmployeeEnum.hireType.find((item) => item.id == cellValue);
      return obj ? obj.value : "不明";
    },
    // 根据员工id删除员工
    async deleteEmployeeById(row) {
      try {
        await this.$confirm(`确定要删除员工【${row.username}】吗？`);
        // 只有点了确定才会进入到下面
        await deleteEmployeeById(row.id);
        // 提示
        this.$message.success(`成功删除员工【${row.username}】`);
        // 重新获取数据渲染
        this.getEmployeeList();
      } catch (error) {
        this.$message.erroe(error);
        console.log(error);
      }
    },
    // 导出excel
    async exportData() {
      // 表头对照
      const headers = {
        姓名: "username",
        手机号: "mobile",
        入职日期: "timeOfEntry",
        聘用形式: "formOfEmployment",
        转正日期: "correctionTime",
        工号: "workNumber",
        部门: "departmentName",
      };
      // 表头
      let excelHeaders = Object.keys(headers);
      // 复杂表头
      const multiHeader = [["姓名", "主要信息", "", "", "", "", "部门"]];
      // 合并表头，合并多个单元格的时候以第一个单元格的内容为主
      const merges = ["A1:A2", "B1:F1", "G1:G2"];

      // 获取所有员工数据
      const { rows: allData } = await getEmployeeList({
        page: 1,
        size: this.total,
      });
      // 对象数组转换成二维数组
      const data = this.formatJson(allData, headers);
      // 懒加载
      import("@/vendor/Export2Excel").then((excel) => {
        // excel是文件导出的对象，调用方法
        excel.export_json_to_excel({
          header: excelHeaders, //表头，数组（内部还是 数组，内部每一个数组表示一行数据 ） 必填
          data, //具体数据 必填
          filename: "员工表", //文件名字，非必填
          autoWidth: true, //宽度自适应，非必填
          bookType: "xlsx", //文件类型，非必填
          multiHeader, //复杂表头
          merges, //合并表头
        });
      });
    },
    // 对象数组转换成二维数组 [{}] => [[]]
    formatJson(allData, headers) {
      let arr = [];
      allData.forEach((item) => {
        let tempArr = [];
        for (const key in headers) {
          if (Object.hasOwnProperty.call(headers, key)) {
            // 单元格的值
            let value = item[headers[key]];
            if (key == "聘用形式") {
              let temp = EmployeeEnum.hireType.find((obj) => obj.id == value);
              tempArr.push(temp ? temp.value : "未知");
            } else if (key == "入职日期" || key == "转正日期") {
              // 转换格式
              let date = formatDate(value);
              tempArr.push(date);
            } else {
              tempArr.push(value);
            }
          }
        }
        arr.push(tempArr);
      });
      return arr;
    },
    // 生成二维码并显示弹框
    showQrCode(url) {
      if (url) {
        this.showCodeDialog = true; //数据更新了，但是弹层不会立即出现，页面渲染是异步的
        this.$nextTick(() => {
          // 等页面渲染完成，弹层出现，再转化二维码显示
          QRCode.toCanvas(this.$refs.codeCanvas, url);
        });
      } else {
        this.$message.error("这是默认头像，该用户还未上传头像");
      }
    },
    // 关闭二维码弹层
    closeCodeDialog() {
      this.showCodeDialog = false;
    },
    // 显示分配角色的弹层
    async editRole(id) {
      console.log(id);
      this.roleUserId = id; //props赋值和渲染是异步的！！！
      // 调用子组件的方法--异步的，加上await
      await this.$refs.RoleDialog.getUserDetailById(id); 
      // 最后再显示
      this.showRoleDialog = true;
    },
    // 关闭角色弹层
    closeRoleDialog() {
      this.showRoleDialog = false;
    },
  },
  created() {
    // 请求员工数据
    this.getEmployeeList();
  },
};
</script>

<style scope >
.emp-staff-photo {
  border-radius: 50%;
  width: 100px;
  height: 100px;
  padding: 10px;
}
</style>
